package Local;

import java.util.ArrayList;

public class local {
	
	void solRandom(dgbi.BiGrafo big){
		for(dgbi.Node n : big.iv1){
			big.v1.add((int)(Math.random()*100)%big.v1.size(), n);
		}
		
		for(dgbi.Node n : big.iv2){
			big.v2.add((int)(Math.random()*100)%big.v2.size(), n);
		}
		
		big.iv1.clear();
		big.iv2.clear();
		
	}
        void solConctAlFinal(dgbi.BiGrafo big){  
            // Agrega V1' y V2' al final de V1 y V2 respectivamente 
		for(dgbi.Node n : big.iv1){
			big.v1.add(n);
		}
		
		for(dgbi.Node n : big.iv2){
			big.v2.add(n);
		}
		
		big.iv1.clear();
		big.iv2.clear();
		
	}
	
	public int BusqlocalLarga(dgbi.BiGrafo big){
		System.out.println("Inicio Local...");
                
                solConctAlFinal(big);
                
                
                int contador = (big.cantEjesFijo+big.cantEjesParticionAAgregar)*(big.cantEjesFijo+big.cantEjesParticionAAgregar);
               
		int mejorI = -1;
		int mejorJ = -1;
		boolean mejorEnV1 = true;						//si hizo swap en V1 o V2
		int mejorCantCortes = big.cantidadCruces();
                
                System.out.print("mejorCantCortesL2: ");
                System.out.println(mejorCantCortes);
		int cortesAntes = mejorCantCortes;
		int cortesDespues = 0;
		
		boolean mejoro = true;							//si pudo mejorar
		
		for(int hasta = contador; hasta>0 && mejoro;hasta--){

			
			mejoro = false;
			//Mover nodos dentro de V1
			for(int i = 0; i < big.v1.size();i++){
				if(!big.v1.get(i).fijo){ //&& !big.v1.get(i+1).fijo){
					for(int j = 0; j <= big.v1.size();j++){                     //llego hasta <= porque puedo insertar en la ulttima posicion
						if(i != j){                                         // no inserto en la mismo posicion
							//cortesAntes =  big.cantidadCruces();
							insertar(big.v1,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.cantidadCruces();
							else
								cortesDespues =  big.cantidadCruces();
							if(cortesAntes > cortesDespues){
								if(cortesDespues < mejorCantCortes){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = true;
									mejoro = true;
								}
							}
						
							restablecer(big,big.v1,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
			// Mover nodos dentro de V2
			for(int i = 0; i < big.v2.size();i++){
				if(!big.v2.get(i).fijo){ //&& !big.v2.get(i+1).fijo){
					for(int j = 0; j <= big.v2.size();j++){
						if(i != j){
							//cortesAntes =  big.cantidadCruces();
							insertar(big.v2,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.cantidadCruces();
							else
								cortesDespues =  big.cantidadCruces();
							if(cortesAntes > cortesDespues){
								if(cortesDespues < mejorCantCortes){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = false;
									mejoro = true;
								}
							}
							restablecer(big,big.v2,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
		//	Actualizo Solucion
			if(mejoro){
				
				System.out.println("Mejoro");
                                
                                System.out.print("difCortesL2: ");
                                System.out.println(cortesAntes-mejorCantCortes);
				if(mejorEnV1)
					insertar(big.v1,mejorI,mejorJ);	
				else
					insertar(big.v2,mejorI,mejorJ);
			}
			else
				System.out.println("no Mejoro");
                    
                        cortesAntes =  mejorCantCortes;
		}
                System.out.println("Cruces final: "+mejorCantCortes);
                return mejorCantCortes;
	}
	
        public int Busqlocal(dgbi.BiGrafo big){
		System.out.println("Inicio Local...");
           //     solConctAlFinal(big);
                int contador = (big.cantEjesFijo+big.cantEjesParticionAAgregar)*(big.cantEjesFijo+big.cantEjesParticionAAgregar);
               
                System.out.println("Cruces Inicial: "+big.cantidadCruces());
                
		int mejorI = -1;
		int mejorJ = -1;
		boolean mejorEnV1 = true;				//si movio 1 nodo en V1 o V2
		
		int cortesAntes = 0;
		int cortesDespues = 0;
		int difCortes = -1;                                     //quiero la max diferencia, 
             //   int difCortes = -1;
                
		boolean mejoro = true;							//si pudo mejorar
		
                for(int pos = 0; pos< big.v1.size();pos++){
                    
                    System.out.print("cortesPos ");
                    System.out.print(pos+" :");
                    System.out.println(big.CortesDeV1(pos));
                }
                
		for(int hasta = contador; hasta>0 && mejoro;hasta--){

			mejoro = false;
			// Por cada nodo de V1 en la pos i
			for(int i = 0; i < big.v1.size();i++){
                                
                                 // si no esta fijo
				if(!big.v1.get(i).fijo){ //&& !big.v1.get(i+1).fijo){
                                        cortesAntes = big.CortesDeV1(i);
                                        // lo muevo a cada posicion j dentro de V1 y me quedo con la mejor
					for(int j = 0; j <= big.v1.size();j++){     //llego hasta <= porque puedo insertar en la ulttima posicion
                                                if(i != j){                                         // no inserto en la mismo posicion
							insertar(big.v1,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.CortesDeV1(j-1);
							else
								cortesDespues =  big.CortesDeV1(j);
							if(cortesAntes > cortesDespues){
								if((cortesAntes-cortesDespues > difCortes) || (difCortes ==-1)){
									difCortes = cortesAntes-cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = true;
									mejoro = true;
								}
							}
						
							restablecer(big,big.v1,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
			// Mover nodos dentro de V2
			for(int i = 0; i < big.v2.size();i++){
				if(!big.v2.get(i).fijo){ 
                                    cortesAntes = big.CortesDeV2(i);
					for(int j = 0; j <= big.v2.size();j++){
						if(i != j){
							insertar(big.v2,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.CortesDeV2(j-1);
							else
								cortesDespues =  big.CortesDeV2(j);
							if(cortesAntes > cortesDespues){
								if((cortesAntes - cortesDespues > difCortes) || (difCortes ==-1)){
									difCortes = cortesAntes-cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = false;
									mejoro = true;
								}
							}
							restablecer(big,big.v2,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
		//	Actualizo Solucion
			if(mejoro){
				
				System.out.println("Mejoro");
                                System.out.print("difCortesL: ");
                                System.out.println(difCortes);
                                
                                
				if(mejorEnV1)
					insertar(big.v1,mejorI,mejorJ);	
				else
					insertar(big.v2,mejorI,mejorJ);
			}
			else
				System.out.println("no Mejoro");
                    
                   difCortes = -1;
		}
                System.out.println("Cruces final: "+big.cantidadCruces());
                return big.cantidadCruces();
	}
	
        
        
     /*   
	public int Busqlocal(dgbi.BiGrafo big){
		System.out.println("Inicio Local...");
                solConctAlFinal(big);
                int contador = (big.cantEjesFijo+big.cantEjesParticionAAgregar)*(big.cantEjesFijo+big.cantEjesParticionAAgregar);
               
		int mejorI = -1;
		int mejorJ = -1;
		boolean mejorEnV1 = true;				//si movio 1 nodo en V1 o V2
		
		int cortesAntes = 0;
		int cortesDespues = 0;
		int mejorCantCortes = -1;
             //   int difCortes = -1;
                
		boolean mejoro = true;							//si pudo mejorar
		
                for(int pos = 0; pos< big.v1.size();pos++){
                    
                    System.out.print("cortesPos ");
                    System.out.print(pos+" :");
                    System.out.println(big.CortesDeV1(pos));
                }
                
		for(int hasta = contador; hasta>0 && mejoro;hasta--){

			mejoro = false;
			// Por cada nodo de V1 en la pos i
			for(int i = 0; i < big.v1.size();i++){
                                
                                 // si no esta fijo
				if(!big.v1.get(i).fijo){ //&& !big.v1.get(i+1).fijo){
                                        cortesAntes = big.CortesDeV1(i);
                                        // lo muevo a cada posicion j dentro de V1 y me quedo con la mejor
					for(int j = 0; j <= big.v1.size();j++){     //llego hasta <= porque puedo insertar en la ulttima posicion
                                                if(i != j){                                         // no inserto en la mismo posicion
							insertar(big.v1,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.CortesDeV1(j-1);
							else
								cortesDespues =  big.CortesDeV1(j);
							if(cortesAntes > cortesDespues){
								if((cortesDespues < mejorCantCortes) || (mejorCantCortes ==-1)){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = true;
									mejoro = true;
								}
							}
						
							restablecer(big,big.v1,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
			// Mover nodos dentro de V2
			for(int i = 0; i < big.v2.size();i++){
				if(!big.v2.get(i).fijo){ 
                                    cortesAntes = big.CortesDeV2(i);
					for(int j = 0; j <= big.v2.size();j++){
						if(i != j){
							insertar(big.v2,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues =  big.CortesDeV2(j-1);
							else
								cortesDespues =  big.CortesDeV2(j);
							if(cortesAntes > cortesDespues){
								if((cortesDespues < mejorCantCortes) || (mejorCantCortes ==-1)){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = false;
									mejoro = true;
								}
							}
							restablecer(big,big.v2,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
		//	Actualizo Solucion
			if(mejoro){
				
				System.out.println("Mejoro");
                                System.out.print("mejorCantCortesL: ");
                                System.out.println(mejorCantCortes);
                                
                                
				if(mejorEnV1)
					insertar(big.v1,mejorI,mejorJ);	
				else
					insertar(big.v2,mejorI,mejorJ);
			}
			else
				System.out.println("no Mejoro");
                    
                   mejorCantCortes = -1;
		}
                System.out.println("Cruces final: "+big.cantidadCruces());
                return big.cantidadCruces();
	}
              */  
        /*
	public int Busqlocal(dgbi.BiGrafo big){         // devuelve la cantidad de cortes, modifica big
		System.out.println("Inicio Local...");
                
                solRandom(big);
                int contador = (big.cantEjesFijo+big.cantEjesParticionAAgregar)*(big.cantEjesFijo+big.cantEjesParticionAAgregar);
		int mejorI = -1;
		int mejorJ = -1;
		boolean mejorEnV1 = true;						//si hizo swap en V1 o V2
		int mejorCantCortes = big.cantidadCruces();
		int cortesAntes = 0;
		int cortesDespues = 0;
		
		boolean mejoro = true;							//si pudo mejorar
		
		for(int hasta = contador; hasta>0 && mejoro;hasta--){
					
			mejoro = false;
			//Mover nodos dentro de V1
			for(int i = 0; i < big.v1.size();i++){
				if(!big.v1.get(i).fijo){// && !big.v1.get(i+1).fijo){
					for(int j = 0; j <= big.v1.size();j++){
						if(i != j){
							cortesAntes = big.CortesDeV1(i);
							insertar(big.v1,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues = big.CortesDeV1(j-1);
							else
								cortesDespues = big.CortesDeV1(j);
							if(cortesAntes > cortesDespues){
								if(cortesDespues < mejorCantCortes){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = true;
									mejoro = true;
								}
							}
						
							restablecer(big,big.v1,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
			// Mover nodos dentro de V2
			for(int i = 0; i < big.v2.size();i++){
				if(!big.v2.get(i).fijo){// && !big.v2.get(i+1).fijo){
					for(int j = 0; j <= big.v2.size();j++){
						if(i != j){
							cortesAntes = big.CortesDeV2(i);
							insertar(big.v2,i,j);					//muevo el nodo de i a j
							if(i<j)
								cortesDespues = big.CortesDeV2(j-1);
							else
								cortesDespues = big.CortesDeV2(j);
							if(cortesAntes > cortesDespues){
								if(cortesDespues < mejorCantCortes){
									mejorCantCortes = cortesDespues;
									mejorI = i;
									mejorJ = j;
									mejorEnV1 = false;
									mejoro = true;
								}
							}
							restablecer(big,big.v2,j,i);				//muevo el nodo de j a i
						
						}
					
					}
				
				}
			}
		
		//	Actualizo Solucion
			if(mejoro){
				
				System.out.println("Mejoro");
				if(mejorEnV1)
					insertar(big.v1,mejorI,mejorJ);	
				else
					insertar(big.v2,mejorI,mejorJ);
			}
			else
				System.out.println("no Mejoro");
		}
                
                return mejorCantCortes;
	}
*/
	private static void insertar(ArrayList<dgbi.Node> v, int i, int j){
		dgbi.Node n = v.get(i);
		v.remove(i);
		if(i<j){
			v.add(j-1, n);
		}
		else{
			v.add(j, n);
		}
	}
	
	private static void restablecer(dgbi.BiGrafo big, ArrayList<dgbi.Node> v, int j, int i){

		if(j<i){
			dgbi.Node n = v.get(j);
			v.remove(j);
			v.add(i, n);
		}
		else{
			dgbi.Node n = v.get(j-1);
			v.remove(j-1);
			v.add(i, n);
		}
		
	}
	
	
}